' constants
const true  = -1
const false = not true

const TOK_EOF = 1
const TOK_EOL = 2
const TOK_STRING = 3
const TOK_COMMENT = 4
const TOK_SPACE = 5

' because of stupid BASIC rules,
' CRLF cannot be a constant but
' has to be a global variable
dim shared CRLF as string : CRLF = chr$(13) + chr$(10)
if instr$(_os$, "[LINUX]") then _
  CRLF = chr$(10)

' setup
deflng a-z
randomize timer
option base 1

' globals
dim shared basic_code$
dim shared c_code$
dim shared basic_lines : basic_lines = 1
dim shared curr_line   : curr_line   = 1
dim shared curr_char   : curr_char   = 1

' flags
dim shared del_c`   : del_c`   = true
dim shared verbose` : verbose` = false

dim source_name$ : source_name$ = command$
dim c_name$
dim ext_char
dim source_file  : source_file  = freefile
dim c_file       : c_file       = freefile

if left$(ltrim$(command$), 3) = "/c " then
  del_c` = false
  source_name$ = mid$(command$, 4)
end if

do while instr(command$, ".", ext_char) <> 0
  ext_char = instr(command$, ".", ext_char)
loop

if ext_char = 0 or rtrim$(right$(source_name$, len(source_name$) - ext_char)) <> ".btc" then _
  print_error "Unknown file extension"

c_name$ = left$(source_name$, len(source_name$) - ext_char) + ".c"

open source_name$ for input as #source_file
basic_code$ = input$(lof(source_file), source_file)
close #source_file

translate_basic

open c_name$ for output as #c_file

print #c_file, _
      "/* C Header Includes */"; CRLF;         _
      "#include <stdio.h>"; CRLF;              _
      "#include <stdlib.h>"; CRLF;             _
      "#include <setjmp.h>"; CRLF;             _
      "#include <math.h>"; CRLF;               _
_
      "/* BtCT Globals */"; CRLF;              _
      "jmp_buf gosub_stack[256];"; CRLF;       _
      "char gosub_pointer;"; CRLF;             _
_
      "/* Main Function */"; CRLF;             _
      "int main(int argc, char **argv)"; CRLF; _
      "{"; CRLF;                               _
_
      c_code$; CRLF;                           _
_
      "  return 0;"; CRLF;                     _
      "}"; CRLF

close #c_file

if del_c` then
  shell _dontwait _hide "tcc " + c_file$
  kill c_file$
end if
system

'$INCLUDE:'DeclareLibs.bas'

sub print_error (error_string$)
  print "Error: line "; str$(curr_line); ": "; error_string$
  close
  sleep
  system
end sub

sub translate_basic
  dim token
  do
    token = get_token
    select case token
      case TOK_EOL : curr_line = curr_line + 1 : curr_char = curr_char + len(CRLF) - 1
      case TOK_COMMENT : goto_eol
      case TOK_SPACE : skip_space
      else : print_error "Invalid token"
    end select
  loop until curr_line > basic_lines
end sub

sub skip_space
  while get_token = TOK_SPACE : curr_char + 1 : wend
end sub

sub goto_eol
  while get_token <> TOK_EOL : curr_char = curr_char + 1 : wend
  curr_line = curr_line + 1
  curr_char = curr_char + len(CRLF) - 1
end sub

function get_token
  select case mid$(basic_code$, curr_char, 1)
    case is = chr$(34) : get_token = TOK_STRING
    case is = " ", is = chr$(9) : get_token = TOK_SPACE
    case is = CRLF : get_token = TOK_EOL
  end select
end function

